declare
fun {NewGRLock}
   Token1={NewCell unit}
   Token2={NewCell unit}
   CurThr={NewCell unit}

   fun {GetLock}
      if {Thread.this}\=@CurThr then Old New in
         {Exchange Token1 Old New}
         {Wait Old}
         Token2:=New
         CurThr:={Thread.this}
         true
      else false end
   end

   proc {ReleaseLock}
      CurThr:=unit
      unit=@Token2
   end
in
   'lock'(get:GetLock release:ReleaseLock)
end
